#include <gtest/gtest.h>
#include <plog/Log.h>
#include "trt_define.h"
#include "utils/logger.h"
#include "utils/elapsed_timer.h"
#include "utils/affine_matrix.h"

_TRT_INFER_BEGIN
class LoggerTest : public ::testing::Test
{
protected:
    LoggerTest() {}
    ~LoggerTest() override {}
    void SetUp() override {}
    void TearDown() override {}
};

template<typename... _Args>
void test_template(int dim_size, _Args ... args)
{
    LOG_INFO << "test_template";
    const int dim_size_array[] = { dim_size, args... };
    LOGI << sizeof...(args) + 1;
}


TEST_F(LoggerTest, test_logger)
{
    trt_infer::Logger::instance().init();
    trt_infer::Logger::instance().AddTextFileAppender("test_logger.txt", 8000, 3);
    trt_infer::Logger::instance().instance();
    LOG_INFO << "test_logger";
}

TEST_F(LoggerTest, test_template)
{
    test_template(4, 1, 3, 224.0, 224);
}

TEST_F(LoggerTest, ElapsedTimer)
{
    ElapsedTimer timer;
    timer.start();
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    float latency = timer.stop();
    LOG_INFO << "latency: " << latency;
}

TEST_F(LoggerTest, AffineMatrixWapper)
{
    AffineMatrixWapper affine_matrix;
    affine_matrix.move(1, 2);
    EXPECT_EQ(affine_matrix.i2d(), std::vector<float>({1, 0, 1, 0, 1, 2}));
    EXPECT_EQ(affine_matrix.d2i(), std::vector<float>({1, 0, -1, 0, 1, -2}));
    affine_matrix.rotate(30);

    affine_matrix.scale(0.5, 0.5);
    affine_matrix.crop(0, 0, 224, 224);
    std::vector<float> d2i = affine_matrix.d2i();
    std::vector<float> i2d = affine_matrix.i2d();
    LOG_INFO << "d2i: " << d2i[0] << " " << d2i[1] << " " << d2i[2] << " " << d2i[3] << " " << d2i[4] << " " << d2i[5];
    LOG_INFO << "i2d: " << i2d[0] << " " << i2d[1] << " " << i2d[2] << " " << i2d[3] << " " << i2d[4] << " " << i2d[5];
    std::vector<float> i2d_expect = {0.43301270189221935, -0.24999999999999997, -0.06698729810778059, 0.24999999999999997, 0.43301270189221935, 1.1160254037844386};
    std::vector<float> d2i_expect = {1.7320508075688774, 0.9999999999999999, -1.0, -0.9999999999999998, 1.7320508075688774, -2.0};
    EXPECT_EQ(d2i.size(), 6);
    EXPECT_EQ(i2d.size(), 6);
    for(int i = 0; i < 6; i++)
    {
        EXPECT_NEAR(d2i[i], d2i_expect[i], 1e-6);
        EXPECT_NEAR(i2d[i], i2d_expect[i], 1e-6);
    }
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

_TRT_INFER_END
